<?php
/*
Tests the functionality of this web application

*/

set_include_path(get_include_path().':/Applications/MAMP/bin/php5/lib/php'); //set path to PHPUnit.php directory
require_once('PHPUnit.php');
require_once('../lib/arc2/ARC2.php');
require_once('../lib/moriarty/httprequest.class.php');
//define('CONVERT','http://convert.test.talis.com/');
define('CONVERT','http://localhost/');
define('DOCS', CONVERT.'/tests/documents/');

define('SPARQLXML', DOCS.'sparql-select-sample.srx');
define('FACETSXML', DOCS.'facet.xml');
define('JSON', DOCS.'rdf.json');
define('RDF', DOCS.'sample.rdf');
define('RDF_URI', 'http://api.talis.com/stores/silkworm-dev/items/1179061567369');
define('HTML', DOCS.'sample.html');
define('TURTLE', DOCS.'rdf.ttl');



class ConvertUAT extends PHPUnit_TestCase{
	
	function convert($data_uri,   $input=false, $output=false, $accept_header=false){
		$uri = CONVERT.'?';
		
		if(is_array($data_uri)){	
			foreach($data_uri as $d_u){
				$uri .= 'data-uri[]='.urlencode($d_u).'&';
			}
		} else {
			$uri .= 'data-uri[]='.urlencode($data_uri);			
		}

		$uri.= ($input)? '&input='.urlencode($input) : '';
		$uri.= ($output)? '&output='.urlencode($output) :'';
//		echo $uri."\n";
		$request = new HTTPRequest('GET', $uri);
		if($accept_header) $request->set_accept($accept_header);
		return $request->execute();
	}
	
	function __construct($name)
	{
		$this->PHPUnit_TestCase($name);
	}
	
	function setUp(){
	}
	
	function tearDown(){
	
	}
	
	function test_invalidJSON_fails_gracefully(){
		$uri = DOCS.'/bad-json.php';
		$response = $this->convert($uri,false,'turtle');
		$this->assertEquals('400', $response->status_code);		
	}
	
	function test_bad_url_gives_404(){
		$uri = CONVERT.'/bad-unavailable-url/foo/bar';
		$request = new HTTPRequest('GET', $uri);
		$response = $request->execute();
		$this->assertEquals('404', $response->status_code);		
	}
	
	function test_irretrievable_data_uri_causes_502(){
		$response = $this->convert(CONVERT.'/bad-unavailable-url/foo/bar', false,'json');
	
		$this->assertEquals('502', $response->status_code);		
	}

	function test_unavailable_conversion_causes_400(){
		$response = $this->convert(SPARQLXML,false,'turtle');
		$this->assertEquals('400', $response->status_code);		
	}


	 function test_no_dataURI(){
		$response = $this->convert('',false,'json');
		$this->assertEquals('400', $response->status_code);		
	 }
	
	function test_no_accept_header_or_output_param_defaults_to_html(){
		$response = $this->convert(RDF);
		$this->assertEquals('200', $response->status_code);	
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);	
	}

	function test_bad_data_uri_returns_400(){
		$response = $this->convert(' hello world ');
		$this->assertEquals('400', $response->status_code);		
	}

	function test_bad_input_returns_400(){
		$response = $this->convert(RDF, ' hello world ');
		$this->assertEquals('400', $response->status_code);		
	}
	
	function test_bad_output_returns_400(){
		$response = $this->convert(RDF, 'rdf', ' hello world ');
		$this->assertEquals('400', $response->status_code);		
	}

	
	function test_RDFa_Rendering(){
		$response = $this->convert(RDF, 'rdf-xml', 'html');
		file_put_contents('documents/output.html', $response->body);
		#get as JSON for easier comparison
		$json1 = json_decode($this->convert(RDF, 'rdf-xml', 'json')->body, 1);
		$json2 = json_decode($this->convert(DOCS.'/output.html', 'rdf-html', 'json')->body, 1);
		foreach($json1[RDF_URI] as $p => $objs){
			# check that s and p are present  in second rendering
			$this->assertTrue( isset($json2[RDF_URI][$p]) );
			foreach($json2[RDF_URI][$p] as $n => $obj){
				# make sure the onject keys are sorted in same order
				asort($json2[RDF_URI][$p][$n]);
			}
			if(isset($json2[RDF_URI][$p])){
				foreach($objs as $o){
					asort($o);
					$this->assertTrue( in_array($o, $json2[RDF_URI][$p]) );					
				}
			}
		}
	}
	
	
	function test_RDF_Graphs_merge_without_confusing_bnodes(){
		// $g1 = json_decode($this->convert(DOCS.'/merge1.ttl', 'rdf-turtle', 'json')->body, 1);
		// $g2 = json_decode($this->convert(DOCS.'/merge2.ttl', 'rdf-turtle', 'json')->body, 1);
		$g3 = json_decode($this->convert(array(DOCS.'/merge1.ttl', DOCS.'/merge2.ttl'), 'rdf-turtle', 'json')->body, 1);
		$this->assertTrue(isset($g3['http://example.com/1']));
		$this->assertEquals(2, count($g3['http://example.com/1']['http://xmlns.com/foaf/0.1/name']));
		$this->assertEquals(2, count($g3['http://example.com/1']['http://xmlns.com/foaf/0.1/knows']));
	}
	
	# SPARQL RESULTS
	
	function test_sparql_xml_to_json(){ 
		$response = $this->convert(SPARQLXML,false,'json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data['head']));
		
 	 } 
	function test_sparql_xml_to_html(){ 
		
		$response = $this->convert(SPARQLXML,false,'html');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//table[@class="sparql"])'));

 	 } 
	
	# Facets 
	
	function test_facets_xml_to_html(){ 
		$response = $this->convert(FACETSXML,false,'html');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//div[@class="facet"])'));

 	 } 
	function test_facets_xml_to_json(){ 
		$response = $this->convert(FACETSXML,false,'json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data['head']));

 	 } 
	
	# RDF/JSON
	
	function test_rdfjson_to_html(){ 
		$response = $this->convert(JSON,false,'html');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//div[@class="resources"])'));
 	 } 
	function test_rdfjson_to_rdfxml(){ 
		$response = $this->convert(JSON,false,'rdf');
		$expected = 'application/rdf+xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);

		$this->assertTrue($doc->saveXML());

 	 } 
	function test_rdfjson_to_rss1(){ 
		
		$response = $this->convert(JSON,false,'rss');
		$expected = 'application/rss+xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);
		$this->assertTrue($doc->saveXML() );

 	 } 
	function test_rdfjson_to_jsonp(){ 
		$response = $this->convert(JSON,false,'jsonp');
		$expected = 'application/javascript';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$this->assertTrue(strpos($response->body,'callback(')===0 );

 	 } 
	function test_rdfjson_to_rdfjson(){ 
		$response = $this->convert(JSON,false,'json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data));
 	 } 

	function test_rdfjson_to_ntriples(){ 
		$response = $this->convert(JSON,false,'ntriples');
		$expected = 'text/plain';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$parser = ARC2::getTurtleParser();
		$parser->parse(false, $response->body);
		$data = $parser->getSimpleIndex(0);
		$this->assertEquals(json_decode(file_get_contents(JSON), true), $data);
 	 } 


	function test_rdfjson_to_turtle(){ 
		$response = $this->convert(JSON,false,'turtle');
		$expected = 'text/n3';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);

		$this->assertTrue(strpos($response->body, '@prefix')===0);
 	 } 


	function test_rdfjson_to_TriX(){ 
		$response = $this->convert(JSON,false,'trix');
		$expected = 'application/xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);
		$this->assertTrue($doc->saveXML());
 	 } 
	function test_rdfjson_to_exhibitjson(){ 
		$response = $this->convert(JSON,false,'exhibit-json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data));
 	 } 
	function test_rdfjson_to_exhibitjsonp(){ 
		$response = $this->convert(JSON,false,'exhibit-jsonp');
		$expected = 'application/javascript';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$this->assertTrue(strpos($response->body,'callback(')===0 );
 	 } 
	function test_rdfjson_to_exhibitHTML(){ 
		$response = $this->convert(JSON,false,'exhibit');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//body[@id="exhibit"])'));
 	 } 
	

	# Turtle
	
	function test_turtle_to_html(){ 
		$response = $this->convert(TURTLE,false,'html');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//div[@class="resources"])'));
 	 } 
	function test_turtle_to_rdfxml(){ 
		$response = $this->convert(TURTLE,false,'rdf');
		$expected = 'application/rdf+xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);

		$this->assertTrue($doc->saveXML());

 	 } 
	function test_turtle_to_rss1(){ 
		
		$response = $this->convert(TURTLE,false,'rss');
		$expected = 'application/rss+xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);
		$this->assertTrue($doc->saveXML() );

 	 } 
	function test_turtle_to_jsonp(){ 
		$response = $this->convert(TURTLE,false,'jsonp');
		$expected = 'application/javascript';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$this->assertTrue(strpos($response->body,'callback(')===0 );

 	 } 
	function test_turtle_to_json(){ 
		$response = $this->convert(TURTLE,false,'json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data));
 	 } 
	function test_turtle_to_TriX(){ 
		$response = $this->convert(TURTLE,false,'trix');
		$expected = 'application/xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);
		$this->assertTrue($doc->saveXML());
 	 } 
	function test_turtle_to_exhibitjson(){ 
		$response = $this->convert(TURTLE,false,'exhibit-json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data));
 	 } 
	function test_turtle_to_exhibitjsonp(){ 
		$response = $this->convert(TURTLE,false,'exhibit-jsonp');
		$expected = 'application/javascript';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$this->assertTrue(strpos($response->body,'callback(')===0 );
 	 } 
	function test_turtle_to_exhibitHTML(){ 
		$response = $this->convert(TURTLE,false,'exhibit');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//body[@id="exhibit"])'));
	} 
	

	# RDF/XML
	
	function test_rdfxml_to_html(){ 
		$response = $this->convert(RDF,false,'html');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//div[@class="resources"])'));
 	 } 
	function test_rdfxml_to_rdfxml(){ 
		$response = $this->convert(RDF,false,'rdf');
		$expected = 'application/rdf+xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);

		$this->assertTrue($doc->saveXML());

 	 } 
	function test_rdfxml_to_rss1(){ 
		
		$response = $this->convert(RDF,false,'rss');
		$expected = 'application/rss+xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);
		$this->assertTrue($doc->saveXML() );

 	 } 
	function test_rdfxml_to_jsonp(){ 
		$response = $this->convert(RDF,false,'jsonp');
		$expected = 'application/javascript';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$this->assertTrue(strpos($response->body,'callback(')===0 );

 	 } 
	function test_rdfxml_to_json(){ 
		$response = $this->convert(RDF,false,'json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data));
 	 } 

	function test_rdfxml_to_turtle(){ 
		$response = $this->convert(JSON,false,'turtle');
		$expected = 'text/n3';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);

		$this->assertTrue(strpos($response->body, '@prefix')===0);
 	 } 
	function test_rdfxml_to_TriX(){ 
		$response = $this->convert(RDF,false,'trix');
		$expected = 'application/xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);
		$this->assertTrue($doc->saveXML());
 	 } 
	function test_rdfxml_to_exhibitjson(){ 
		$response = $this->convert(RDF,false,'exhibit-json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data));
 	 } 
	function test_rdfxml_to_exhibitjsonp(){ 
		$response = $this->convert(RDF,false,'exhibit-jsonp');
		$expected = 'application/javascript';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$this->assertTrue(strpos($response->body,'callback(')===0 );
 	 } 
	function test_rdfxml_to_exhibitHTML(){ 
		$response = $this->convert(RDF,false,'exhibit');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//body[@id="exhibit"])'));
	} 
	


	# SemHTML
	
	function test_semHTML_to_html(){ 
		$response = $this->convert(HTML,false,'html');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		@$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//div[@class="resources"])'));

 	 } 
	function test_semHTML_to_rdfxml(){ 
		$response = $this->convert(HTML,false,'rdf');
		$expected = 'application/rdf+xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);
		$this->assertTrue($doc->saveXML() );

 	 } 
	function test_semHTML_to_rss1(){ 
		$response = $this->convert(HTML,false,'rss');
		$expected = 'application/rss+xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);
		$this->assertTrue($doc->saveXML() );

 	 } 
	function test_semHTML_to_jsonp(){ 
		$response = $this->convert(HTML,false,'json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data));

 	 } 
	function test_semHTML_to_rdfjson(){ 
		$response = $this->convert(HTML,false,'json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data));

 	 } 
	function test_semHTML_to_TriX(){ 
		$response = $this->convert(HTML,false,'trix');
		$expected = 'application/xml';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadXML($response->body);
		$this->assertTrue($doc->saveXML());
 	 } 
	function test_semHTML_to_exhibitjson(){ 
		$response = $this->convert(HTML,false,'exhibit-json');
		$expected = 'application/json';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$data = json_decode($response->body, true);
		$this->assertTrue(is_array($data));
 	 } 
	function test_semHTML_to_exhibitjsonp(){ 
		$response = $this->convert(HTML,false,'exhibit-jsonp');
		$expected = 'application/javascript';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$this->assertTrue(strpos($response->body,'callback(')===0 );
 	 } 
	function test_semHTML_to_exhibitHTML(){ 
		$response = $this->convert(HTML,false,'exhibit');
		$expected = 'text/html';
		$actual = array_shift(explode(';', $response->headers['content-type']));
		$this->assertEquals($expected, $actual);
		$doc = new DomDocument();
		$doc->loadHTML($response->body);
		$xpath  = new DomXPath($doc);
		$this->assertTrue($xpath->evaluate('count(//body[@id="exhibit"])'));
 	 } 
	
	
		
	function test_conneg(){
		foreach(array('application/json', 'text/html' ,'application/rdf+xml','text/plain', 'text/n3') as $mtype){
			$response = $this->convert(RDF, false, false, $mtype);
			$expected = $mtype;
			$actual = array_shift(explode(';', $response->headers['content-type']));
//			(var_dump($response->headers));
			$this->assertEquals($expected, $actual);
	//		echo $actual."\n";
		}
		
	}
	
	function test_outputParam(){
		foreach(array('application/json' => 'json', 'text/html' => 'html' ,'application/rdf+xml' => 'rdf','text/n3' => 'turtle', 'text/plain' => 'ntriples') as $mtype => $k){
			$response = $this->convert(RDF, false, $k, $mtype);
			$expected = $mtype;
			$actual = array_shift(explode(';', $response->headers['content-type']));
			$this->assertEquals($expected, $actual);
	//		echo $actual."\n";
		}
		
	}
	

}
foreach(get_declared_classes() as $class)
{
	$suite = new PHPUnit_TestSuite($class);
	$result = PHPUnit::run($suite);
	print $result->toString();
}
?>
